package com.xxl.job.executor.util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.*;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;
public class JAXBUtil2 {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private JAXBContext jaxbContext;
    public JAXBUtil2(Class<?> clazz) {
        try {
            jaxbContext = JAXBContext.newInstance(clazz);
        } catch (JAXBException e) {
            logger.error("get jaxbContext instance fail:", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * Xml->Java Object.
     */
    public Object toEntity(String xml) {
        try {
            StringReader reader = new StringReader(xml);
            //Unmarshaller 此接口实现XML--->bean的转换
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            return unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            logger.error("unMarshalXml error:", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * Xml->Java Object, 支持大小写敏感或不敏感.
     */
    public Object toEntityWithSensitive(String xml, boolean caseSensitive) {
        try {
            String fromXml = xml;
            if (!caseSensitive)
                fromXml = xml.toLowerCase();
            StringReader reader = new StringReader(fromXml);
            //Unmarshaller 此接口实现XML--->bean的转换
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            return unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            logger.error("unMarshalXml error:", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * Java Object->Xml.
     */
    public String toXml(Object root, String encoding) {
        try {
            StringWriter writer = new StringWriter();
            //创建marshaller 接口对象 实现BEAN--->xml转换
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            if (StringUtils.isNotBlank(encoding)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            }
            marshaller.marshal(root, writer);
            return writer.toString();
        } catch (JAXBException e) {
            logger.error("marshaller Bean-->Xml error:", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * Java Object->Xml, 特别支持对Root Element是Collection的情形.
     */
    @SuppressWarnings("unchecked")
    public String toXmlWithWrapper(Collection root, String rootName, String encoding) {
        try {
            CollectionWrapper wrapper = new CollectionWrapper();
            wrapper.collection = root;
            JAXBElement<CollectionWrapper> wrapperElement =
                    new JAXBElement<>(new QName(rootName), CollectionWrapper.class, wrapper);
            StringWriter writer = new StringWriter();
            //创建marshaller 接口对象 实现BEAN--->xml转换
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            if (StringUtils.isNotBlank(encoding)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            }
            marshaller.marshal(wrapperElement, writer);
            return writer.toString();
        } catch (JAXBException e) {
            logger.error("marshaller Bean-->Xml error:", e);
            throw new RuntimeException(e);
        }
    }
    /**
     * 封装Root Element 是 Collection的情况.
     */
    public static class CollectionWrapper {
        @SuppressWarnings("unchecked")
        @XmlAnyElement
        Collection collection;
    }
}